home *** CD-ROM | disk | FTP | other *** search
/ Shareware Super Platinum 8 / Shareware Super Platinum 8.iso / mac / WIN_PRO / DS-1.ZIP;1 / RTT.ZIP / RTTMAIN.C < prev    next >
Encoding:
C/C++ Source or Header  |  1992-02-10  |  11.0 KB  |  397 lines

  1. #include "rtt.h"
  2.  
  3. /*
  4.  * prototypes for static functions.
  5.  */
  6. hidden novalue add_tdef Params((char *name));
  7.  
  8. /*
  9.  * refpath is used to locate the standard include files for the Icon.
  10.  *  run-time system. If patchpath has been patched in the birary of rtt,
  11.  *  the string was patched in is used for refpath.
  12.  */
  13. char patchpath[MaxPath+18] = "%PatchStringHere->";
  14. char *refpath = RefPath;
  15.  
  16. /*
  17.  * The relative path to grttin.h and rt.h depends on whether it's
  18.  *  interpreted as relative to where rtt.exe is or where rtt.exe is
  19.  *  invoked.
  20.  */
  21.  
  22. #if MSDOS
  23. char *grttin_path = "../h/grttin.h";
  24. char *rt_path = "../h/rt.h";
  25. #else                    /* MSDOS */
  26. char *grttin_path = "../src/h/grttin.h";
  27. char *rt_path = "../src/h/rt.h";
  28. #endif                    /* MSDOS */
  29.  
  30. static char *ostr = "ECPD:I:U:d:cir:st:x";
  31. static char *options = 
  32.    "[-E] [-C] [-P] [-Dname[=[text]]] [-Uname] [-Ipath] [-dfile]\n    \
  33. [-rpath] [-tname] [-x] [files]";
  34.  
  35. /*
  36.  *  Note: rtt presently does not process system include files. If this
  37.  *   is needed, it may be necessary to add other options that set
  38.  *   manifest constants in such include files.  See pmain.c for the
  39.  *   stand-alone preprocessor for examples of what's needed.
  40.  */
  41.  
  42. char *progname = "rtt";
  43. char *compiler_def;
  44. FILE *out_file;
  45. char *inclname;
  46. int def_fnd;
  47. char *largeints = NULL;
  48.  
  49. int iconx_flg = 0;
  50. int enable_out = 0;
  51.  
  52. static char *curlst_nm = "rttcur.lst";
  53. static FILE *curlst;
  54. static char *cur_src;
  55.  
  56. extern line_cntrl;
  57.  
  58. /*
  59.  * tdefnm is used to construct a list of identifiers that
  60.  *  must be treated by rtt as typedef names.
  61.  */
  62. struct tdefnm {
  63.    char *name;
  64.    struct tdefnm *next;
  65.    };
  66.  
  67. static char *dbname = "rt.db";
  68. static int pp_only = 0;
  69. static char *opt_lst;
  70. static char **opt_args;
  71. static char *in_header;
  72. static struct tdefnm *tdefnm_lst = NULL;
  73.  
  74. /*
  75.  * getopt() variables
  76.  */
  77. extern int optindex;        /* index into parent argv vector */
  78. extern int optopt;        /* character checked for validity */
  79. extern char *optarg;        /* argument associated with option */
  80.  
  81. #if TURBO
  82. unsigned _stklen = 20000;
  83. #endif                    /* TURBO */
  84.  
  85. int main(argc, argv)
  86. int argc;
  87. char **argv;
  88.    {
  89.    int c;
  90.    int nopts;
  91.    char buf[MaxFileName];        /* file name construction buffer */
  92.    struct fileparts *fp;
  93.  
  94.    /*
  95.     * See if the location of include files has been patched into the
  96.     *  rtt executable.
  97.     */
  98.    if (strlen(patchpath)>18)
  99.       refpath = patchpath+18;
  100.  
  101.    /*
  102.     * Initialize the string table and indicate that File must be treated
  103.     *  as a typedef name.
  104.     */
  105.    init_str();
  106.    add_tdef("FILE");
  107.  
  108.    /*
  109.     * By default, the spelling of white space in unimportant (it can
  110.     *  only be significant with the -E option) and #line directives
  111.     *  are required in the output.
  112.     */
  113.    whsp_image = NoSpelling;
  114.    line_cntrl = 1;
  115.  
  116.    /*
  117.     * opt_lst and opt_args are the options and corresponding arguments
  118.     *  that are passed along to the preprocessor initialization routine.
  119.     *  Their number is at most the number of arguments to rtt.
  120.     */
  121.    opt_lst = (char *)alloc((unsigned)argc);
  122.    opt_args = (char **)alloc((unsigned)(sizeof (char *)) * argc);
  123.    nopts = 0;
  124.  
  125.    /*
  126.     * Process options.
  127.     */
  128.    while ((c = getopt(argc, argv, ostr)) != EOF)
  129.       switch (c) {
  130.      case 'E': /* run preprocessor only */
  131.             pp_only = 1;
  132.             if (whsp_image == NoSpelling)
  133.                whsp_image = NoComment;
  134.             break;
  135.          case 'C':  /* retain spelling of white space, only effective with -E */
  136.             whsp_image = FullImage;
  137.             break;
  138.           case 'P': /* do not produce #line directives in output */
  139.             line_cntrl = 0;
  140.             break;
  141.           case 'd': /* -d name: name of data base */
  142.             dbname = optarg;
  143.             break;
  144.          case 'r':  /* -r path: location of include files */
  145.             refpath = optarg;
  146.             break;
  147.          case 't':  /* -t ident : treat ident as a typedef name */
  148.             add_tdef(optarg);
  149.             break;
  150.          case 'x':  /* produce code for interpreter rather than compiler */
  151.             iconx_flg = 1;
  152.             break;
  153.          case 'D':  /* define preprocessor symbol */
  154.          case 'I':  /* path to search for preprocessor includes */
  155.          case 'U':  /* undefine preprocessor symbol */
  156.  
  157.             /*
  158.              * Save these options for the preprocessor initialization routine.
  159.              */
  160.             opt_lst[nopts] = c;
  161.             opt_args[nopts] = optarg;
  162.             ++nopts;
  163.             break;
  164.          default:
  165.             show_usage();
  166.          }
  167.  
  168.    if (iconx_flg)
  169.       compiler_def = "#define COMPILER 0\n";
  170.    else
  171.       compiler_def = "#define COMPILER 1\n";
  172.    in_header = (char *)alloc((unsigned)strlen(refpath) +
  173.       (unsigned)strlen(grttin_path) + 1);
  174.    strcpy(in_header, refpath);
  175.    strcat(in_header, grttin_path);
  176.    inclname = (char *)alloc((unsigned)strlen(refpath) +
  177.       (unsigned)strlen(rt_path) + 1);
  178.    strcpy(inclname, refpath);
  179.    strcat(inclname, rt_path);
  180.  
  181.    opt_lst[nopts] = '\0';
  182.  
  183.    /*
  184.     * At least one file name must be given on the command line.
  185.     */
  186.    if (optindex == argc)
  187.      show_usage();
  188.  
  189.    /*
  190.     * When creating the compiler run-time system, rtt outputs a list
  191.     *  of names of C files created, because most of the file names are
  192.     *  not derived from the names of the input files.
  193.     */
  194.    if (!iconx_flg) {
  195.       curlst = fopen(curlst_nm, "w");
  196.       if (curlst == NULL)
  197.          err2("cannot open ", curlst_nm);
  198.       }
  199.  
  200.    /*
  201.     * Unless the input is only being preprocessed, set up the in-memory data
  202.     *  base (possibly loading it from a file).
  203.     */
  204.    if (!pp_only) {
  205.       fp = fparse(dbname);
  206.       if (*fp->ext == '\0')
  207.          dbname = salloc(makename(buf, SourceDir, dbname, DBSuffix));
  208.       else if (!smatch(fp->ext, DBSuffix))
  209.          err2("bad data base name:", dbname);
  210.       loaddb(dbname);
  211.       }
  212.  
  213.    /*
  214.     * Scan file name arguments, and translate the files.
  215.     */
  216.    while (optindex < argc)  {
  217.       trans(argv[optindex]);
  218.       optindex++;
  219.       }
  220.  
  221.    /*
  222.     * Unless the user just requested the preprocessor be run, we
  223.     *   have created C files and updated the in-memory data base.
  224.     *   If this is the compiler's run-time system, we must dump
  225.     *   to data base to a file and create a list of all output files
  226.     *   produced in all runs of rtt that created the data base.
  227.     */
  228.    if (!(pp_only || iconx_flg)) {
  229.       dumpdb(dbname);
  230.       full_lst("rttfull.lst");
  231.       }
  232.    return NormalExit;
  233.    }
  234.  
  235. /*
  236.  * trans - translate a source file.
  237.  */
  238. novalue trans(src_file)
  239. char *src_file;
  240.    {
  241.    char *cname;
  242.    char buf[MaxFileName];        /* file name construction buffer */
  243.    char *buf_ptr;
  244.    char *s;
  245.    struct fileparts *fp;
  246.    struct tdefnm *td;
  247.    struct token *t;
  248.    static char *standardpp = "#define StandardPP\n";
  249.    static char *test_largeints = "#ifdef LargeInts\nyes\n#endif\n";
  250.    static first_time = 1;
  251.  
  252.    cur_src = src_file;
  253.  
  254.    /*
  255.     * Read standard header file for preprocessor directives and
  256.     * typedefs, but don't write anything to output.
  257.     */
  258.    enable_out = 0;
  259.    init_preproc(in_header, opt_lst, opt_args);
  260.    str_src("<rtt initialization>", standardpp, (int)strlen(standardpp));
  261.    str_src("<rtt initialization>", compiler_def, (int)strlen(compiler_def));
  262.    init_sym();
  263.    for (td = tdefnm_lst; td != NULL; td = td->next)
  264.       sym_add(TypeDefName, td->name, OtherDcl, 1);
  265.    init_lex();
  266.    yyparse();
  267.    if (first_time) {
  268.       first_time = 0;
  269.       /*
  270.        * Now that the standard include files have been processed, see if
  271.        *  Largeints is defined and make sure it matches what's in the data base.
  272.        */
  273.       s = "NoLargeInts";
  274.       str_src("<rtt initialization>", test_largeints,
  275.          (int)strlen(test_largeints));
  276.       while ((t = preproc()) != NULL)
  277.           if (strcmp(t->image, "yes"))
  278.              s = "LargeInts";
  279.       if (largeints == NULL) 
  280.          largeints = s;
  281.       else if (strcmp(largeints, s) != 0)
  282.          err2("header file definition of LargeInts/NoLargeInts does not match ",
  283.             dbname);
  284.       }
  285.    enable_out = 1;
  286.  
  287.    /*
  288.     * Make sure we have a .r file or standard input.
  289.     */
  290.    if (strcmp(cur_src, "-") == 0) {
  291.       source("-"); /* tell preprocessor to read standard input */
  292.       cname = salloc(makename(buf, TargetDir, "stdin", CSuffix));
  293.       }
  294.    else {
  295.       fp = fparse(cur_src);
  296.       if (*fp->ext == '\0')
  297.          cur_src = salloc(makename(buf, SourceDir, cur_src, RttSuffix));
  298.       else if (strcmp(fp->ext, RttSuffix) != 0)
  299.          err2("unknown file suffix ", cur_src);
  300.       cur_src = spec_str(cur_src);
  301.  
  302.       /*
  303.        * For the compiler, remove from the data base the list of
  304.        *  files produced from this input file.
  305.        */
  306.       if (!iconx_flg)
  307.          clr_dpnd(cur_src);
  308.       source(cur_src);  /* tell preprocessor to read source file */
  309.       /*
  310.        * For the interprter prepend "x" to the file name for the .c file.
  311.        */
  312.       buf_ptr = buf;
  313.       if (iconx_flg)
  314.          *buf_ptr++ = 'x';
  315.       makename(buf_ptr, TargetDir, cur_src, CSuffix);
  316.       cname = salloc(buf);
  317.       }
  318.  
  319.    if (pp_only)
  320.       output(stdout); /* invoke standard preprocessor output routine */
  321.    else {
  322.       /*
  323.        * For the compiler, non-RTL code is put in a file whose name
  324.        *  is derived from input file name. The flag def_fnd indicates
  325.        *  if anything interesting is put in the file.
  326.        */
  327.       def_fnd = 0;
  328.       if ((out_file = fopen(cname, "w")) == NULL)
  329.          err2("cannot open output file ", cname);
  330.       prologue(); /* output standard comments and preprocessor directives */
  331.       yyparse();  /* translate the input */
  332.       fprintf(out_file, "\n");
  333.       fclose(out_file);
  334.  
  335.       /*
  336.        * For the Compiler, note the name of the "primary" output file
  337.        *  in the data base and list of created files.
  338.        */
  339.       if (!iconx_flg)
  340.          put_c_fl(cname, def_fnd);
  341.       }
  342.    }
  343.  
  344. /*
  345.  * add_tdef - add identifier to list of typedef names.
  346.  */
  347. static novalue add_tdef(name)
  348. char *name;
  349.    {
  350.    struct tdefnm *td;
  351.  
  352.    td = NewStruct(tdefnm);
  353.    td->name = spec_str(name);
  354.    td->next = tdefnm_lst;
  355.    tdefnm_lst = td;
  356.    }
  357.  
  358. /*
  359.  * Add name of file to the output list, and if it contains "interesting"
  360.  *  code, add it to the dependency list in the data base.
  361.  */
  362. novalue put_c_fl(fname, keep)
  363. char *fname;
  364. int keep;
  365.    {
  366.    struct fileparts *fp;
  367.  
  368.    fp = fparse(fname);
  369.    fprintf(curlst, "%s\n", fp->name);
  370.    if (keep)
  371.       add_dpnd(src_lkup(cur_src), fname);
  372.    }
  373.  
  374. /*
  375.  * Print an error message if called incorrectly.
  376.  */
  377. novalue show_usage()
  378.    {
  379.    fprintf(stderr, "usage: %s %s\n", progname, options);
  380.    exit(ErrorExit);
  381.    }
  382.  
  383. /*
  384.  * yyerror - error rountine called by yacc.
  385.  */
  386. novalue yyerror(s)
  387. char *s;
  388.    {
  389.    struct token *t;
  390.  
  391.    t = yylval.t;
  392.    if (t == NULL)
  393.       err2(s, " at end of file");
  394.    else
  395.       errt1(t, s);
  396.    }
  397.